package dao

import (
	"fitness/internal/entity/system"
	"github.com/duke-git/lancet/v2/slice"
	"go.uber.org/zap"
	"gorm.io/gorm"
)

// 角色与菜单对应
type SysRoleMenuDao struct {
	DB           *gorm.DB
	UserRolesDao *SysUserRolesDao
	Log          *zap.Logger
}

func NewSysRoleMenuDao(db *gorm.DB, UserRolesDao *SysUserRolesDao, logger *zap.Logger) *SysRoleMenuDao {
	return &SysRoleMenuDao{
		DB:           db,
		UserRolesDao: UserRolesDao,
		Log:          logger,
	}
}

type RolePermsBO struct {
	RoleCode string   //角色编码
	Perms    []string //权限标识集合
}

type RolePerms struct {
	RoleCode string //角色编码
	Perm     string //权限标识
}

// 创建角色菜单
func (sysRoleMenuDao *SysRoleMenuDao) CreateRoleMenu(roleId uint64, menuIds []uint64) error {
	err := sysRoleMenuDao.DB.Transaction(func(tx *gorm.DB) error {
		//for _, menuId := range menuIds {
		//	menu := entity.SysRoleMenu{
		//		RoleId: roleId,
		//		MenuId: menuId,
		//	}
		//	if err := tx.Create(&menu).Error; err != nil {
		//		return err
		//	}
		//}
		//return nil
		return sysRoleMenuDao.CreateRoleMenuWithDB(tx, roleId, menuIds)
	})
	return err
}

// 创建角色菜单事务
func (sysRoleMenuDao *SysRoleMenuDao) CreateRoleMenuWithDB(DB *gorm.DB, roleId uint64, menuIds []uint64) error {
	for _, menuId := range menuIds {
		menu := system.SysRoleMenu{
			RoleId: roleId,
			MenuId: menuId,
		}
		if err := DB.Create(&menu).Error; err != nil {
			return err
		}
	}
	return nil
}

// 获取权限和拥有权限的角色列表
func (sysRoleMenuDao *SysRoleMenuDao) GetRolePermsList(roleId uint64) []RolePermsBO {
	sql := `SELECT
            t3.perm,
            t2.code role_code
        FROM
            sys_role_menu t1
            INNER JOIN sys_role t2 ON t1.role_id = t2.id AND t2.is_deleted = 0 AND t2.status = 1
            INNER JOIN sys_menu t3 ON t1.menu_id = t3.id
            where type = 4` //type = 4 是按钮
	tx := sysRoleMenuDao.DB.Raw(sql)
	if roleId != 0 {
		tx.Where(" t2.id = ?", roleId)
	}
	var roles []RolePerms
	var m = make(map[string][]string)
	tx.Find(&roles)

	for _, rolePerm := range roles {
		code := rolePerm.RoleCode
		perm := rolePerm.Perm
		perms := m[code]
		if perms == nil || len(perms) == 0 {
			m[code] = []string{perm}
		} else {
			if !slice.Contain(perms, perm) {
				perms = append(perms, perm)
			}
			m[code] = perms
		}
	}
	var bos []RolePermsBO
	for k, v := range m {
		var bo RolePermsBO
		bo.RoleCode = k
		bo.Perms = v
		bos = append(bos, bo)
	}
	return bos
}
